﻿using AutoMapper;
using Comm100.Application.Services;
using Comm100.Framework.Auditing;
using Comm100.Framework.Authorization;
using Comm100.Public.Audit;
using Bot.Application.Dto;
using Bot.Application.Services;
using Bot.Domain.Bo;
using Bot.Domain.Entities;
using Bot.Domain.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;
using Bot.Domain;
using Bot.Domain.Categories.Service;
using Comm100.Framework.Exceptions;

namespace Bot.Application.Chatbots.Service
{
    public class ChatbotAppService : BaseAppService, IChatbotAppService
    {
        private IChatbotDomainService _chatbotDomainService;
        private IIntentDomainService _intentDomainService;
        private IImageDomainService _imageDomainService;
        private IGreetingMessageInChannelDomainService _greetingMessageInChannelDomainService;
        private INoAnswerMessageInChannelDomainService _noAnswerMessageInChannelDomainService;
        private IMessageAfterSeveralConsecutivePossibleAnswersInChannelDomainService _messageAfterSeveralConsecutivePossibleAnswersInChannelDomainService;
        private IWebhookDomainService _webhookDomainService;
        private IResponseDomainService _responseDomainService;
        private IBotVerifyDataManager _botVerifyDataManager;

        public ChatbotAppService(IChatbotDomainService chatDomainService,
            IIntentDomainService intentDomainService,
            IImageDomainService imageDomainService,
            IGreetingMessageInChannelDomainService greetingMessageInChannelDomainService,
            INoAnswerMessageInChannelDomainService noAnswerMessageInChannelDomainService,
            IMessageAfterSeveralConsecutivePossibleAnswersInChannelDomainService messageAfterSeveralConsecutivePossibleAnswersInChannelDomainService,
            IWebhookDomainService webhookDomainService,
            IResponseDomainService responseDomainService,
            IBotVerifyDataManager botVerifyDataManager) : base()
        {
            _chatbotDomainService = chatDomainService;
            _intentDomainService= intentDomainService;
            _imageDomainService = imageDomainService;
            _greetingMessageInChannelDomainService = greetingMessageInChannelDomainService;
            _noAnswerMessageInChannelDomainService = noAnswerMessageInChannelDomainService;
            _messageAfterSeveralConsecutivePossibleAnswersInChannelDomainService = messageAfterSeveralConsecutivePossibleAnswersInChannelDomainService;
            _webhookDomainService = webhookDomainService;
            _responseDomainService = responseDomainService;
            _botVerifyDataManager = botVerifyDataManager;

        }

        [Authorization(BotPermission.MANAGE_BOTS)]
        //[Audit(BotEntity.CHATBOT, AuditAction.DESTROY)]
        public void Delete(Guid id, string include)
        {
            var errorInfo = _botVerifyDataManager.VerifyDelete(id);
            if (errorInfo.Code != 1)
            {
                throw new BusinessException(errorInfo);
            }

            _chatbotDomainService.Delete(id);
        }

        [Authorization(BotPermission.MANAGE_BOTS)]
        //[Audit(BotEntity.CHATBOT, AuditAction.CREATE)]
        public ChatbotDto Add(ChatbotCreateDto dto, bool ifDefault, string projectId)
        {
            var errorInfo = _botVerifyDataManager.VerifyCreate(dto,ifDefault, projectId);
            if (errorInfo.Code != 1)
            {
                throw new BusinessException(errorInfo);
            }

            Chatbot chatbot = _chatbotDomainService.Create(Mapper.Map<Chatbot>(dto), ifDefault, projectId);
            return Mapper.Map<ChatbotDto>(chatbot);
        }

        [Authorization(BotPermission.MANAGE_BOTS)]
        ////[Audit(BotEntity.CHATBOT, AuditAction.UPDATE)]
        public ChatbotDto Update(Guid id, ChatbotUpdateDto dto)
        {
            Chatbot chatbot = _chatbotDomainService.Update(id, Mapper.Map<ChatbotUpdateBo>(dto));
            return Mapper.Map<ChatbotDto>(chatbot);
        }

        public ChatbotDto Get(Guid id, string include)
        {
            var errorInfo = _botVerifyDataManager.VerifyId(id);
            if (errorInfo.Code != 1)
            {
                if(errorInfo.Code == 50004)
                {
                    throw new EntityNotFoundException(id, typeof(ChatbotDto));
                }

                throw new BusinessException(errorInfo);
            }

            //组装一个大对象
            Chatbot chatbot = _chatbotDomainService.Get(id, include: include);
            ChatbotDto chatbotDto = Mapper.Map<ChatbotDto>(chatbot);
            return chatbotDto;
        }

        public IEnumerable<ChatbotDto> GetList(string include, string channel)
        {
            IEnumerable<Chatbot> list = _chatbotDomainService.List(include, channel);
            return Mapper.Map<IEnumerable<ChatbotDto>>(list);
        }

        public void Delete(Guid id)
        {
            var errorInfo = _botVerifyDataManager.VerifyDelete(id);
            if (errorInfo.Code != 1)
            {
                throw new BusinessException(errorInfo);
            }
            _chatbotDomainService.Delete(id);
        }

        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="botId"></param>
        /// <returns>返回资源的下载地址</returns>
        public string Export(Guid botId)
        {
            return string.Empty;
        }
        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="botId"></param>
        /// <param name="filePath"></param>
        /// <returns>返回OperationId</returns>
        public OperationDto Import(Guid botId, string filePath)
        {
            return new OperationDto { };
        }
        /// <summary>
        /// 训练
        /// </summary>
        /// <param name="botId"></param>
        /// <returns>返回Operation</returns>
        public OperationDto Train(Guid botId)
        {
            return new OperationDto { };
        }
        /// <summary>
        /// 测试
        /// </summary>
        /// <param name="botId"></param>
        /// <param name="testRequestBody"></param>
        /// <returns></returns>
        public TestBotResponseDto Test(Guid botId, TestRequestBodyDto testRequestBody)
        {
            return new TestBotResponseDto { };
        }
    }
}
